As you will know, every file on a unixoid system has some meta-data like owner,
group and permission bits.
This is of course also true for files part of some Debian package.
And it is not very surprising that different files should have different
permissions. Or even different owners or groups.
Which file has which settings is of course for the package maintainer to
decide and Debian would not be Debian if there were not ways for the
user to give their own preferences and have them preserved.
This post is thus about how those settings end up in the package and
what is to be observed when doing it.
As you will also have heard, a
.deb file is simply a tar
archive stored as part of an
ar archive, as you can verify by
unpacking a package manually:
$ ar t reprepro_4.8.1-1_amd64.deb
debian-binary
control.tar.gz
data.tar.gz
$ ar p reprepro_4.8.1-1_amd64.deb data.tar.gz gunzip tar -tvvf -
drwxr-xr-x root/root 0 2011-10-10 12:05 ./
drwxr-xr-x root/root 0 2011-10-10 12:05 ./etc/
drwxr-xr-x root/root 0 2011-10-10 12:05 ./etc/bash_completion.d/
-rw-r--r-- root/root 19823 2011-10-10 12:05 ./etc/bash_completion.d/reprepro
drwxr-xr-x root/root 0 2011-10-10 12:05 ./usr/
drwxr-xr-x root/root 0 2011-10-10 12:05 ./usr/share/
--More--
(For unpacking stuff from scripts, you should of course use
dpkg-deb --fsys-tarfile instead of
ar gunzip.
Above example is about the format, not a recipe to unpack files).
This already explains how the information is usually encoded in the package:
A tar file contains that information for each contained file and dpkg is
simply using that information.
(As tar stores numeric owner and group information, that limits group
and owner information to users and groups with fixed numbers, i.e. 0-99.
Other cases will be covered later.)
The question for the maintainer is now: Where is the information which file
has which owner/group/permissions in the
.tar inside the
.deb,
and the answer is simple:
It's taken from the files to be put into the
.deb.
This means that package tools could simply be implemented first by simply
calling tar and there is no imminent need to write you own tar generator.
It also means that the maintainer has full control and
does not have to learn new descriptive languages or tools to change permissions,
but can simply put the usually shell commands into
debian/rules.
There are some disadvantages, though: A normal user cannot change ownership
of files and one has to make sure all files have proper permissions and owners.
This means that
dpkg-deb -b (or the usually used wrapper
dh_builddeb)
must be run in some context where you could change the file ownership to root first.
This means you either need to be root, or at least to fake being root by using fakeroot.
(While this could be considered some ugly workaround, it also means upstream's
make install is run believing to be root, which also avoids some --
for a packager -- quite annoying automatisms in upstream build scripts assuming
a package is not installed system wide if not installed as root).
Another problem are random build host characteristics changing how files
are created in the directory later given to
dpkg-deb -b.
For example an umask which might make all files non-world-readable by default.
The usual workaround is to first fix up all those permissions.
Most packages use
dh_fixperms for this, which also sets executable
bits according to some simple rules and has some more special cases so that
the overall majority of packages does not need to look at permissions at all.
So using some
debhelper setup, every special permissions and
all owner/group information for owner groups with fixed numbers only needs
to be set using the normal command line tools between
dh_fixperms
and
dh_builddeb.
Everything else happens automatically.
Note that
games is a group with fixed gid. So it is not necessary
(and usually a bug) to change group-ownership of files withing the package
to group games in maintainer scripts (
postinst,...).
If a user wants to change permissions or ownership of a file,
dpkg allows this using the
dpkg-statoverride command.
This command essentially manages a list of files to get special
treatment and ownership and permission information they should get.
This way a user can specify that files should have different permissions
and this setting is applied if a new version of this file is installed by
dpkg.
Being a user setting especially means, that packages (that means their
maintainer scripts) should not usually use dpkg-statoverride.
There are two exceptions, though: Different permissions based on
interaction with the user (e.g. asking question with debconf) and
dynamically allocated users/groups with dynamic id.
In both cases one should note that settings to dpkg-statoverride
are settings of the user, so the same care should be given as to files
in
/etc, especially one should never override something the user
has set in there. (I can think of no example where calling
dpkg-statoverride --add without
dpkg-statoverride --list
in some maintainer script is not a serious bug:
Either you override user settings or you are using debconf as a registry.
Moral
To recap, your package is doing something wrong if:
-
Your maintainer scripts unconditionally change permissions of files
within the package (Those should either be set within the package or
you miss user configuration in dpkg-statoverride).
-
Your maintainer scripts call dpkg-statoverride --add
without having checked first whether the user already has done so
with different values.